#include "holder.h"
#include "nest.h"

Holder::Holder(QWidget *parent) :
    QWidget(parent)
{
//#if QT_VERSION >= 0x040704
#ifndef Q_WS_MAEMO_6
    setWindowFlags(Qt::FramelessWindowHint);
#endif


    bgcol = QColor(0,128,0,255);
    bcol = QColor(0,208,0,255);
    this->setPalette(QPalette(bgcol,bgcol));


    bord = new Bord(bcol, this);
    plr << new Player(0, QColor(255,0,0,255), this);
    plr << new Player(1, QColor(0,0,255,255), this);

    cpl = 0;
    sbob = 0;
    snest = 0;

    last_act = illegal;

    for (int i=0; i<2; ++i) {
        for (int j=0; j<Player::pcs; ++j) {
            connect(plr[i]->bobs[j], SIGNAL(got_me(Bob*)), this, SLOT(get_bob(Bob*)));
        }
    }

    for (int i=0; i<Bord::nn; ++i) {
        connect(bord->nests[i], SIGNAL(come_here(Nest*)), this, SLOT(get_nest(Nest*)));
    }



//    button = new QPushButton("Animated Button",this);
//    button->show();
    anim = new QPropertyAnimation(this);
    anim->setPropertyName("geometry");
    anim->setDuration(500);
    anim->setEasingCurve(QEasingCurve::OutCubic);



    connect(anim,SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), this, SLOT(lockkey(QAbstractAnimation::State,QAbstractAnimation::State)));

    pagain = new QPushButton(QString("PLAY"), this);
    nothanks = new QPushButton(QString("EXIT"),this);

    pagain->hide();
    nothanks->hide();

    pagain->setFlat(true);
    nothanks->setFlat(true);


    connect(pagain,SIGNAL(clicked()),this,SLOT(newgame()));
    connect(nothanks,SIGNAL(clicked()),this,SLOT(close()));

}

void Holder::lockkey(QAbstractAnimation::State nstate,QAbstractAnimation::State ostate) {
    if (nstate == QAbstractAnimation::Running && ostate == QAbstractAnimation::Stopped) {
        for (int i=0; i<2; ++i) {
            for (int j=0; j<Player::pcs; ++j) {
                plr[i]->bobs[j]->blockSignals(true);
            }
        }
        for (int i=0; i<Bord::nn; ++i) {
            bord->nests[i]->blockSignals(true);
        }
    }

    if (nstate == QAbstractAnimation::Stopped && ostate == QAbstractAnimation::Running) {
        for (int i=0; i<2; ++i) {
            for (int j=0; j<Player::pcs; ++j) {
                plr[i]->bobs[j]->blockSignals(false);
            }
        }
        for (int i=0; i<Bord::nn; ++i) {
            bord->nests[i]->blockSignals(false);
        }
    }
}



void Holder::get_bob(Bob* bob) {
    if (bob->state != Bob::taken) {
        sbob = bob;
        if (last_act == pointess) {
            bool res = takeaway(sbob->id, sbob->plid);
            if (res) {
                last_act = pointless;
            }
        }
//        qDebug() << "got bob" << sbob;
    }
}


void Holder::get_nest(Nest* nest) {

    for (int i=0; i<2; ++i) {
        for (int j=0; j<Player::pcs; ++j) {
//            qDebug() << "bops" << i << j <<  plr[i]->bobs[j]->isHidden() <<  plr[i]->bobs[j]->state << plr[i]->bobs[j]->geometry();
        }
    }


    if (sbob || (plr[cpl]->used_bobs < Player::pcs)) {

        for (int i=0; i< Player::pcs; ++i) {
            if (plr[cpl]->bobs[i]->state == Bob::unused) {
                sbob = plr[cpl]->bobs[i];
                break;
            }
        }
        if (!sbob) return ;
        if ((last_act == pointless || last_act == illegal) && nest != sbob->nest) {
            snest = nest;
            act_t res = act(sbob->id, snest->id, sbob->plid );
//            qDebug() << res;
            if (res != illegal) {
                last_act = res;
                sbob = 0;
                snest = 0;
            }
            if (res == gameover) endgame();
        }
    }

}

void Holder::resizeEvent(QResizeEvent *e) {
    QSize sz = e->size();
    bord->resize(sz.width()*0.6, sz.height()-20);
//    bord->resize(sz.height()-20, sz.height()-20);
//    bord->resize(64, 64);
//    qDebug() << "bsc,bs" << QSize(sz.width()*0.6, sz.height()-20) << bord->size() << size();
    bord->move((sz.width() - bord->width())/2, (sz.height() - bord->height())/2);

    for (int i=0;i<2;++i) {
        plr[i]->plb->resize(Nest::sz.width()+4, (Nest::sz.height()+4)*Player::pcs);
//        qDebug() << i << plr[i]->plb->size() << Nest::sz;
    }


    plr[0]->plb->move(10,10);
    plr[1]->plb->move(sz.width()-10-plr[1]->plb->width(),10);
//    qDebug() << "resizing holder";
}


Holder::act_t Holder::act(int bid, int nid, int pid) {


    if (    bid < 0 || bid >= Player::pcs
         || nid < 0 || nid >= Bord::nn
         || pid < 0 || pid >= 2 ) return illegal;


    Bob* bob = plr[cpl]->bobs[bid];
    Nest* nest = bord->nests[nid];

    if (    pid != cpl
         || bob->state == Bob::taken
         || !(nest->empty)) return illegal;

    if (    bob->state == Bob::ingame
            && (   !(nest->neighs.contains(bob->nest))
                   || (plr[0]->used_bobs < Player::pcs || plr[1]->used_bobs < Player::pcs))) return illegal;


    if (bob->state == Bob::ingame) {
        bob->nest->bob = 0;
        bob->nest->empty = true;
    }

    bob->nest = nest;
    nest->bob = bob;
    nest->empty = false;

    if (bob->state == Bob::unused) {

        bob->state = Bob::ingame;
        plr[cpl]->used_bobs += 1;

        QRect g = QRect(bob->pos()+plr[cpl]->plb->pos(), bob->size() );

        bob->hide();

//        plr[cpl]->plb->lay->removeWidget(bob);
//        plr[cpl]->plb->lay->update();
        bob->setParent(this);

        plr[cpl]->plb->removebob(bob);

        bob->setGeometry(g);
        bob->show();

//        qDebug() << "lay" << plr[cpl]->plb->lay->count() << plr[cpl]->plb->rect();

    }


    anim->setTargetObject(bob);
    anim->setStartValue(bob->geometry());
    anim->setEndValue(QRect(nest->pos() + bord->pos(), nest->size()));
    anim->start();

//    bob->setGeometry(QRect(nest->pos() + bord->pos(), nest->size()));

    last_act = (bord->have_line(nid,cpl)) ? pointess : pointless;

    if (last_act == pointess) plr[cpl]->pts += 1;

    int ncpl = (cpl+1)%2;

    if (   (last_act == pointess && plr[ncpl]->lost_bobs >= Player::pcs-3)
           || (last_act != pointess && plr[ncpl]->islandlocked())) last_act = gameover;

    if ( last_act != gameover) cpl = ncpl;


//    qDebug() << "\n";
//    for (int i=0; i<2; ++i) {
//        for (int j=0; j<Player::pcs; ++j) {
//            if (plr[i]->bobs[j]->state == Bob::unused) {
//                qDebug() << i << j << plr[i]->bobs[j]->state
//                         << plr[i]->bobs[j]->grad->center()
//                         << plr[i]->bobs[j]->grad->radius()
//                         << plr[i]->bobs[j]->grad->focalPoint()
//                         << plr[i]->bobs[j]->grad->stops();
//            }
//        }
//    }

//    endgame();

    return last_act;

}

bool Holder::takeaway(int bid, int pid) {
//    qDebug() << "take away bid and pid" << bid <<  pid;
    if (last_act != pointess || pid != cpl || bid < 0 || bid >= Player::pcs ) return false;

    Bob* bob = plr[cpl]->bobs[bid];
    if (bob->state != Bob::ingame) return false;

    bob->nest->bob = 0;
    bob->nest->empty = true;
    bob->nest = 0;
    plr[cpl]->lost_bobs += 1;

    int ncpl = (cpl+1)%2;


    connect(anim, SIGNAL(finished()), this, SLOT(bringbobback()));

    anim->setTargetObject(bob);
    anim->setStartValue(bob->geometry());
//    qDebug() << plr[ncpl]->plb->lay->geometry().bottom();
    anim->setEndValue(QRect( plr[ncpl]->plb->geometry().bottomLeft(), bob->size()));
    anim->start();



    bob->state = Bob::taken;

    if (plr[cpl]->islandlocked()) endgame();

    return true;

}


void Holder::bringbobback() {
//    sbob->setParent(plr[(sbob->plid+1)%2]->plb);
//    plr[(sbob->plid+1)%2]->plb->lay->addWidget(sbob);
    plr[(sbob->plid+1)%2]->plb->addbob(sbob);
    disconnect(anim, SIGNAL(finished()), this, SLOT(bringbobback()));
    sbob = 0;
}


void Holder::newgame() {


//    qDebug() << "newgame";
//    return;
    cpl = 0;
    sbob = 0;
    snest = 0;

    last_act = illegal;

    for (int i=0; i<2; ++i) {
        plr[i]->pts = 0;
        plr[i]->used_bobs = 0;
        plr[i]->lost_bobs = 0;


        for (int j=0; j<Player::pcs; ++j) {
            plr[i]->bobs[j]->state = Bob::unused;
            plr[i]->bobs[j]->nest = 0;
            if (plr[i]->bobs[j]->parent() != plr[i]->plb) {
                plr[(i+1)%2]->plb->removebob(plr[i]->bobs[j]);
                plr[i]->bobs[j]->resize(Nest::sz);
                plr[i]->plb->addbob(plr[i]->bobs[j]);

            }
        }

//        qDebug() << "cound" << plr[i]->plb->lay->count() << plr[i]->plb->bobs << plr[i]->col;
    }


    for (int i=0; i<Bord::nn; ++i) {
        bord->nests[i]->empty = true;
        bord->nests[i]->bob = 0;
    }


    pagain->hide();
    nothanks->hide();
}


void Holder::endgame() {

    pagain->setGeometry(width()/9., height()/3., width()/3., height()/3.);
    nothanks->setGeometry(width()*5./9., height()/3., width()/3., height()/3.);

    fnt.setPixelSize(pagain->height()/2.);

    pagain->setFont(fnt);
    nothanks->setFont(fnt);

    if (pagain->isHidden()) pagain->show();
    if (nothanks->isHidden()) nothanks->show();

    pagain->raise();
    nothanks->raise();
//    qDebug() << pagain->geometry() << nothanks->geometry();


}
